home *** CD-ROM | disk | FTP | other *** search
/ HPAVC / HPAVC CD-ROM.iso / WINER.ZIP / GETNAMES.ASM < prev    next >
Assembly Source File  |  1992-05-13  |  7KB  |  150 lines

  1. ;********** GETNAMES.ASM - loads a group of matching file names into an array
  2. ;
  3. ;Copyright (c) 1991 Ethan Winer
  4. ;
  5. ;
  6. ;Usage:
  7. ;
  8. ;   DECLARE FUNCTION GetNames%(Array$())
  9. ;   REDIM Array$(1 TO 1)            'be sure to use REDIM and not DIM
  10. ;   Array$(1) = "*.*"               'or any other valid file specification
  11. ;   NumFiles = GetNames%(Array$())  'load all the names in one operation
  12. ;   FOR X = 1 TO NumFiles           'for each file that was found
  13. ;     PRINT Array$(X)               'print each name
  14. ;   NEXT
  15. ;   PRINT NumFiles; "matching files were found"
  16.  
  17.  
  18. .Model Medium, Basic
  19.     Extrn B$RDIM:Proc       ;this internal routine redimensions an array
  20.     Extrn B$ASSN:Proc       ;this internal routine assigns a string
  21.     Extrn B$FLEN:Proc       ;this internal routine returns a string's length
  22.  
  23.     DTAType Struc           ;define the DOS Disk Transfer Area structure
  24.       Intern  DB 21 Dup (?) ;this is used by DOS internally
  25.       FAttr   DB ?          ;this holds the file attribute
  26.       FTime   DW ?          ;this holds the file time
  27.       FDate   DW ?          ;this holds the file date
  28.       FSize   DD ?          ;this holds the file size
  29.       FName   DB 13 Dup (?) ;this holds the file name and extension
  30.     DTAType Ends
  31.  
  32. .Data
  33.     DTA DB Size DTAType Dup (?) ;DOS will place each file's information here
  34.     NumFiles   DW 0             ;this tracks how many file names were read
  35.     SpecLength DW 0             ;this remembers the length of the file spec
  36.  
  37. .Code
  38.  
  39. GetNames Proc Uses SI DI, Array:Word
  40.  
  41.     Local Buffer[80]:Byte   ;we'll copy the file spec here to add a CHR$(0)
  42.  
  43. ;-- Create a local Disk Transfer Area for our own use.
  44.     Lea  DX,DTA             ;show DOS where the new DTA is to be located
  45.     Mov  AH,1Ah             ;set DTA service
  46.     Int  21h                ;call DOS to do it
  47.  
  48. ;-- Read the array descriptor and get the search spec from the first element,
  49. ;   then copy it to the stack appending a CHR$(0) byte (ASCIIZ string).
  50.     Mov  SI,Array           ;get the address of the string array descriptor
  51.     Mov  BX,[SI+0Ah]        ;now BX holds the adjusted offset value
  52.     Mov  AX,4               ;each element is four bytes long
  53.     Mul  Word Ptr [SI+10h]  ;multiply that by the first element number
  54.     Add  BX,AX              ;now BX holds the address of the first element
  55.     
  56.     Push DS                 ;push the source string's segment and address
  57.     Push BX                 ;  in anticipation of calling B$ASSN below
  58.     Xor  AX,AX              ;a zero means that the source is a descriptor
  59.     Push AX                 ;pass that on as well
  60.     
  61.     Push BX                 ;now pass the descriptor address to B$FLEN
  62.     Call B$FLEN             ;this returns the length in AX
  63.     Mov  SpecLength,AX      ;save the length locally for a moment
  64.     
  65.     Lea  AX,Buffer          ;get the destination address on the stack
  66.     Push SS                 ;pass the segment to assign into
  67.     Push AX                 ;and then the address
  68.     Push SpecLength         ;non-zero means we're assigning to a fixed-length
  69.     Call B$ASSN             ;copy the file spec to the stack
  70.  
  71.     Lea  BX,Buffer          ;retrieve the starting address of the stack spec
  72.     Mov  DX,BX              ;copy that to DX where DOS expects it below
  73.     Add  BX,SpecLength      ;point just past the end of the string
  74.     Mov  Byte Ptr [BX],0    ;and append the trailing zero byte
  75.  
  76. ;-- Count the number of names that match the search specification.
  77.     Mov  AH,4Eh             ;specify the DOS Find First matching name service
  78.     Mov  CX,00100111b       ;this attribute will match any type of file
  79.     Xor  BX,BX              ;BX will accumulate the number of names we find
  80.  
  81. CountNames:
  82.     Int  21h                ;call DOS to see if there's a matching name
  83.     Jc   DoneCount          ;if the carry is set there's no more names
  84.     Inc  BX                 ;otherwise, show we found another one
  85.     Mov  AH,4Fh             ;tell DOS to find the next matching name
  86.     Jmp  CountNames         ;and continue until there are no more
  87.  
  88. DoneCount:
  89.     Mov  NumFiles,BX        ;remember how many files we found for later
  90.     Or   BX,BX              ;did the search fail on the first name?
  91.     Jz   Exit               ;yes, exit and return a count of zero
  92.  
  93. ;-- Now that we know how many file names there are, REDIM the string array.
  94.     Mov  AX,1               ;specify an LBOUND of 1
  95.     Push AX                 ;pass that on to B$RDIM
  96.     Push BX                 ;and pass on the new UBOUND value
  97.     Mov  AL,4               ;each element descriptor comprises four bytes
  98.     Push AX                 ;pass that on too (knowing AH = 0 saves a byte)
  99.     
  100.     Mov  BX,Array           ;get the array descriptor address again
  101.     Push [BX+08]            ;pass the existing array Features word
  102.     Push BX                 ;show where the array descriptor is located
  103.     Call B$RDIM             ;finally, redimension the array as appropriate
  104.  
  105. ;-- This is the main processing loop that reads and assigns each name found.
  106.     Mov  AH,4Eh             ;specify the DOS Find First matching name service
  107.     Lea  DX,Buffer          ;load the address of the file spec again for DOS
  108.     Mov  BX,Array           ;get the array descriptor address again too
  109.     Mov  BX,[BX+0Ah]        ;reload the adjusted offset value
  110.     Add  BX,4               ;now BX holds the address of the first descriptor
  111.  
  112. Do:
  113.     Mov  CX,00100111b       ;specify the attribute for any type of file again
  114.     Int  21h                ;call DOS to see if there's a matching name
  115.     Jc   Exit               ;if the carry is set there's no more names
  116.     Push BX                 ;otherwise, save the current descriptor address
  117.  
  118.     Mov  DI,Offset DTA.FName;search for a zero that marks the end of the name
  119.     Push DS                 ;push DS in anticipation of calling B$ASSN below
  120.     Push DI                 ;and DI too while we have the address handy
  121.  
  122.     Push DS                 ;ensure that ES=DS
  123.     Pop  ES
  124.     Mov  CL,13              ;search up to 13 characters
  125.     Repne Scasb             ;do the search
  126.     Mov  AL,CL              ;save the remainder in AL
  127.     
  128.     Mov  CL,13              ;calculate the number of characters to copy
  129.     Sub  CL,AL              ;and the answer is now in CX
  130.     Dec  CX                 ;except we don't want to include the zero byte
  131.     Push CX                 ;pass that on to B$ASSN
  132.  
  133.     Push DS                 ;show where the destination string descriptor is
  134.     Push BX                 ;by passing the segment and then the address
  135.     Xor  AX,AX              ;a value of zero shows B$ASSN that it's assigning
  136.     Push AX                 ;  to a conventional (not fixed-length) string
  137.     Call B$ASSN             ;assign the current array element to the name
  138.  
  139.     Pop  BX                 ;retrieve the current descriptor address
  140.     Add  BX,4               ;point to the next string array element
  141.     Mov  AH,4Fh             ;specify the DOS Find Next matching name service
  142.     Jmp  Do                 ;continue until there are no more files
  143.  
  144. Exit:
  145.     Mov  AX,NumFiles        ;assign the function output
  146.     Ret                     ;return to BASIC
  147.  
  148. GetNames Endp
  149. End
  150.